/*
 * Copyright (C) 2014 Markus Junginger, greenrobot (http://greenrobot.de)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.bus;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Creates EventBus instances with custom parameters and also allows to install a custom default EventBus instance.
 * Create a new builder using {@link EventBus#builder()}.
 */
public class EventBusBuilder {
	private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();

	boolean logSubscriberExceptions = true;
	boolean logNoSubscriberMessages = true;
	boolean sendSubscriberExceptionEvent = true;
	boolean sendNoSubscriberEvent = true;
	boolean throwSubscriberException;
	boolean eventInheritance = true;
	ExecutorService executorService = DEFAULT_EXECUTOR_SERVICE;

	EventBusBuilder() {
	}

	/** Default: true */
	public EventBusBuilder logSubscriberExceptions(boolean logSubscriberExceptions) {
		this.logSubscriberExceptions = logSubscriberExceptions;
		return this;
	}

	/** Default: true */
	public EventBusBuilder logNoSubscriberMessages(boolean logNoSubscriberMessages) {
		this.logNoSubscriberMessages = logNoSubscriberMessages;
		return this;
	}

	/** Default: true */
	public EventBusBuilder sendSubscriberExceptionEvent(boolean sendSubscriberExceptionEvent) {
		this.sendSubscriberExceptionEvent = sendSubscriberExceptionEvent;
		return this;
	}

	/** Default: true */
	public EventBusBuilder sendNoSubscriberEvent(boolean sendNoSubscriberEvent) {
		this.sendNoSubscriberEvent = sendNoSubscriberEvent;
		return this;
	}

	/**
	 * Fails if an subscriber throws an exception (default: false).
	 * <p/>
	 * Tip: Use this with BuildConfig.DEBUG to let the app crash in DEBUG mode (only). This way, you won't miss
	 * exceptions during development.
	 */
	public EventBusBuilder throwSubscriberException(boolean throwSubscriberException) {
		this.throwSubscriberException = throwSubscriberException;
		return this;
	}

	/**
	 * By default, EventBus considers the event class hierarchy (subscribers to super classes will be notified).
	 * Switching this feature off will improve posting of events. For simple event classes extending Object directly, we
	 * measured a speed up of 20% for event posting. For more complex event hierarchies, the speed up should be >20%.
	 * <p/>
	 * However, keep in mind that event posting usually consumes just a small proportion of CPU time inside an app,
	 * unless it is posting at high rates, e.g. hundreds/thousands of events per second.
	 */
	public EventBusBuilder eventInheritance(boolean eventInheritance) {
		this.eventInheritance = eventInheritance;
		return this;
	}

	/**
	 * Provide a custom thread pool to EventBus used for async and background event delivery. This is an advanced
	 * setting to that can break things: ensure the given ExecutorService won't get stuck to avoid undefined behavior.
	 */
	public EventBusBuilder executorService(ExecutorService executorService) {
		this.executorService = executorService;
		return this;
	}

	/** Builds an EventBus based on the current configuration. */
	public EventBus build() {
		return new EventBus(this);
	}

}
